// @Author EthanScriptOn
// @Desc
package log

import (
	"errors"
	"gitee.com/fatzeng/srf_switch_basic_components/initialization"
	"gitee.com/fatzeng/srf_switch_basic_components/pool"
	"gitee.com/fatzeng/srf_switch_basic_components/util"
	"gitee.com/fatzeng/srf_switch_log/log_define"
	"gitee.com/fatzeng/srf_switch_log/log_worker_factory"
	"math"
	"reflect"
	"time"
)

var collectPool = func() *initialization.OnceInitializer {
	initializerInstance := initialization.GenerateOnceInitializer(log_define.SwitchLogPositionTag, log_define.LogCollectPoolInitTag)
	if err := initializerInstance.Set(math.MaxInt, func() (result interface{}, err error) {
		return pool.GenerateWorkerPool(1, 1, log_worker_factory.GenerateLoggerCollectWorkerFactory(), 10*time.Minute, pool.GenerateReuseRejectStrategy(), pool.WEIGHT), nil
	}); err != nil {
		panic(err)
	}
	return initializerInstance
}()

func GetCollectPool() (*pool.WorkerPool, error) {
	collectPoolInstance, err := collectPool.Get()
	if err != nil {
		return nil, err
	}
	if _, err = util.Assert(collectPoolInstance, reflect.TypeOf(&pool.WorkerPool{})); err != nil {
		return nil, err
	} else {
		return collectPoolInstance.(*pool.WorkerPool), nil
	}
}

var formatterPool = func() *initialization.OnceInitializer {
	initializerInstance := initialization.GenerateOnceInitializer(log_define.SwitchLogPositionTag, log_define.LogFormatterPoolInitTag)
	if err := initializerInstance.Set(math.MaxInt, func() (result interface{}, err error) {
		return pool.GenerateWorkerPool(1, 1, log_worker_factory.GenerateLoggerCollectWorkerFactory(), 10*time.Minute, pool.GenerateReuseRejectStrategy(), pool.WEIGHT), nil
	}); err != nil {
		panic(err)
	}
	return initializerInstance
}()

func GetFormatterPool() (*pool.WorkerPool, error) {
	formatterPoolInstance, err := formatterPool.Get()
	if err != nil {
		return nil, err
	}
	if _, err = util.Assert(formatterPoolInstance, reflect.TypeOf(&pool.WorkerPool{})); err != nil {
		return nil, err
	} else {
		return formatterPoolInstance.(*pool.WorkerPool), nil
	}
}

var exporterPool = func() *initialization.OnceInitializer {
	initializerInstance := initialization.GenerateOnceInitializer(log_define.SwitchLogPositionTag, log_define.LogExporterPoolInitTag)
	if err := initializerInstance.Set(math.MaxInt, func() (result interface{}, err error) {
		return pool.GenerateWorkerPool(1, 1, log_worker_factory.GenerateLoggerCollectWorkerFactory(), 10*time.Minute, pool.GenerateReuseRejectStrategy(), pool.WEIGHT), nil
	}); err != nil {
		panic(err)
	}
	return initializerInstance
}()

func GetExporterPool() (*pool.WorkerPool, error) {
	exporterPoolInstance, err := exporterPool.Get()
	if err != nil {
		return nil, err
	}
	if _, err = util.Assert(exporterPoolInstance, reflect.TypeOf(&pool.WorkerPool{})); err != nil {
		return nil, err
	} else {
		return exporterPoolInstance.(*pool.WorkerPool), nil
	}
}

var logCenter = func() *initialization.OnceInitializer {
	initializerInstance := initialization.GenerateOnceInitializer(log_define.SwitchLogPositionTag, log_define.LogCenterInitTag)
	if err := initializerInstance.Set(math.MaxInt, func() (result interface{}, err error) {
		return GenerateLogCenter(), nil
	}); err != nil {
		panic(err)
	}
	return initializerInstance
}()

func GetLogCenter() (*LogCenter, error) {
	logCenterInstance, err := logCenter.Get()
	if err != nil {
		return nil, err
	}
	logCenterConversionInstance, ok := logCenterInstance.(*LogCenter)
	if !ok {
		return nil, errors.New("the logCenter instance type is not *LogCenter")
	}
	return logCenterConversionInstance, nil
}

var logInitialization = func() *initialization.OnceInitializer {
	initializerInstance := initialization.GenerateOnceInitializer(log_define.SwitchLogPositionTag, log_define.LogInitializationInitTag)
	if err := initializerInstance.Set(math.MaxInt, func() (result interface{}, err error) {
		conversionCenter, err := GetLogCenter()
		if err != nil {
			return nil, err
		}
		switchLog := GenerateSrfSwitchLog(conversionCenter)
		return switchLog, nil
	}); err != nil {
		panic(err)
	}
	return initializerInstance
}()
